package arena.soldier;

import gameframework.base.MoveStrategy;
import gameframework.base.MoveStrategyStraightLine;
import gameframework.base.SpeedVector;

import gameframework.game.GameMovableDriverDefaultImpl;
import gameframework.game.GameUniverse;
import gameframework.game.MoveBlockerChecker;
import gameframework.game.MoveBlockerCheckerDefaultImpl;
import gameframework.game.SpriteManagerDefaultImpl;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

import arena.base.ArenaMoveBlockers;
import arena.base.MonsterMovableDriver;

public class Tower extends SoldierAbstract {
	private static final int FORCE = 2;
	private static final int HEALTHPOINTS = 100;
	public static final int RENDERING_SIZE = 50;
	
	protected boolean movable = true;
	protected boolean active = true;
	protected int enrageTimer = 0;
	
	private MoveStrategy moveStrat;
	private GameUniverse universe;
	private Canvas canvas;
	private Timer timer;
	private boolean cantShoot = false;
	private final SpriteManagerDefaultImpl spriteManager;

	public Tower(String nom, Canvas defaultCanvas,GameUniverse universe) {
		super(nom, HEALTHPOINTS, FORCE);
		this.universe = universe;
		spriteManager = new SpriteManagerDefaultImpl("images/Tower.gif",
				defaultCanvas, RENDERING_SIZE, 1);
		spriteManager.setTypes(
				//
				"up",				
				"down",
				"right",
				"left"			
				);
		this.canvas = defaultCanvas;
		timer = createTimer();

	}
	
	public void setInterdictionShoot(boolean shoot) {
		if(this.cantShoot==false){
		this.cantShoot = shoot;
		if (cantShoot)
			timer.start();
		}
	}
	
	private Timer createTimer() {
		ActionListener action = new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				cantShoot = false;
				timer.stop();
			}
		};
		return new Timer(1000, action);
	}
	
	public void createBullet(Point tmp){
		if(cantShoot==false){
			MoveBlockerChecker moveBlockerChecker = new MoveBlockerCheckerDefaultImpl();
			moveBlockerChecker.setMoveBlockerRules(new ArenaMoveBlockers());
			GameMovableDriverDefaultImpl monsterDriv = new MonsterMovableDriver();
			Point p = new Point (this.getPosition());
				
			if (tmp.x == -1){		
				p.x = p.x -1000;		
			}
			else if (tmp.y == 1){		
				p.y = p.y +1000;
			}
			else if (tmp.y == -1){		
				p.y = p.y -1000;
			}
			else{
				p.x = p.x + 1000;
			}
			MoveStrategyStraightLine ranStr = new MoveStrategyStraightLine(this.getPosition(), new Point(p));
			monsterDriv.setStrategy(ranStr);
			monsterDriv.setmoveBlockerChecker(moveBlockerChecker);
			Bullet b = new Bullet(canvas);
			b.setPosition(this.getPosition());
			universe.addGameEntity(b);
			b.setDriver(monsterDriv);
		}
	}
	
	public void heal() { //XXX resurrection allowed
		healthPoints = HEALTHPOINTS;
	}
	
	public boolean isActive() {
		return active;
	}

	public void setAlive(boolean aliveState) {
		active = aliveState;
	}
	
	@Override
	public void draw(Graphics g) {
		drawBarLife(g);
		 String spriteType = "";
         Point tmp = getSpeedVector().getDirection();
         movable = true;         

         if (tmp.getX() == -1) {
                 spriteType += "left";
                 this.createBullet(tmp);
                 this.setInterdictionShoot(true);
         } else if (tmp.getY() == 1) {
                 spriteType += "down";
                 this.createBullet(tmp);
                 this.setInterdictionShoot(true);
         } else if (tmp.getY() == -1) {
                 spriteType += "up";
                 this.createBullet(tmp);
                 this.setInterdictionShoot(true);
         } else {
                 spriteType += "right";
                 this.createBullet(tmp);
                 this.setInterdictionShoot(true);

         }
         spriteManager.setType(spriteType);
         spriteManager.draw(g, getPosition());		
	}

	@Override
	public Rectangle getBoundingBox() {
		return (new Rectangle(0, 0, RENDERING_SIZE, RENDERING_SIZE));
	}

	@Override
	public void oneStepMoveAddedBehavior() {
		if (movable) {
			spriteManager.increment();
		}
	}

	@Override
	public SpriteManagerDefaultImpl getSpriteManager() {
		return spriteManager;
	}

	@Override
	public float getHealthPointAtBeginning() {
		return HEALTHPOINTS;

	}

	@Override
	public float getMagic() {
		return 0;
	}

	@Override
	public float getMagicAtBeginning() {
		return 0;
	}

	public void drawBarLife (Graphics g){
		int lifeBarWidth = getBoundingBox().width/2;
		float life = (getHealthPoints()/getHealthPointAtBeginning());
		g.setColor(Color.BLACK);
		g.drawRect(this.getPosition().x+(getBoundingBox().width)/4, this.getPosition().y, lifeBarWidth, 7);
		
		if (life > 0.33){
			g.setColor(Color.GREEN);
		}
		else
			g.setColor(Color.RED);

		//Drawing life bar inside
		g.fillRect((this.getPosition().x+(getBoundingBox().width)/4)+1,this.getPosition().y+1, (int) ((lifeBarWidth-1)*life), 6);
	}
	
	public void setMoveStrategy(MoveStrategy keyStr) {
		setMoveStrategy(keyStr);
	}

	public MoveStrategy getMoveStrategy() {
		return this.moveStrat;
	}
	
	public boolean isEnrage() {		
		return enrageTimer > 0;
	}

	public void setEnrage(int timer) {
		this.enrageTimer = timer;
	}
		
	public void oneStepMove(){
		SpeedVector m = getDriver().getSpeedVector(this);
		SpeedVector m2 = getSpeedVector();
		
		m2.setDirection(m.getDirection());			
		m2.setSpeed(m.getSpeed());
		
		setSpeedVector(m2);		
		oneStepMoveAddedBehavior();			
	}
}		